#include "StdAfx.h"
#include "DraftsDb.h"
#ifdef WIN32_PLATFORM_PSPC
#include "resourceppc.h"
#else
#include "resourcesp.h"
#endif

const TCHAR *CDraftsDb::DB_NAME = _T("Drafts");

CDraftsDb::CDraftsDb(void)
    : CDbBase(DB_NAME, sizeof(Record))
    , m_MaxId(0)
{
}

CDraftsDb::~CDraftsDb(void)
{
}

DWORD CDraftsDb::Open(void)
{
    DWORD Err = CDbBase::Open();
    if (Err != ERROR_SUCCESS)
        return Err;

    UINT Count = GetCount();
    if (Count == UINT_MAX)
        return ERROR_GEN_FAILURE;

    if (Count == 0)
    {
        CString Draft;
        Draft.LoadString(IDS_REC_0_DRAFT);

        UINT AssignedId = 0;
        Add(Draft, &AssignedId);
        ASSERT(AssignedId == CDbBase::FIRST_RECORD_ID);
        UNREFERENCED_PARAMETER(AssignedId);
    }
    else
    {
        Record r = {0};
        Err = m_DbMgr.ReadRecord(Count - 1, (BYTE *)&r, sizeof(Record), NULL);
        if (Err != ERROR_SUCCESS)
            return Err;

        m_MaxId = r.Id;     // Read can fail if empty
    }

    return ERROR_SUCCESS;
}

DWORD CDraftsDb::Add(CString Draft, UINT *pAssignedId)
{
    Record r = {0};
    HRESULT hr = StringCchCopy(
        r.Draft,
        sizeof(r.Draft) / sizeof(TCHAR),
        Draft);
    if (FAILED(hr))
        return ERROR_INSUFFICIENT_BUFFER;

    r.Id = m_MaxId + 1;

    UINT Count = GetCount();
    if (Count == UINT_MAX)
        return ERROR_GEN_FAILURE;

    DWORD Err = m_DbMgr.WriteRecord(Count, (BYTE *)&r, sizeof(Record));
    if (Err != ERROR_SUCCESS)
        return Err;

    m_MaxId++;

    if (pAssignedId)
        *pAssignedId = r.Id;

    return ERROR_SUCCESS;
}

DWORD CDraftsDb::Get(UINT Index, UINT *pId, CString *pDraft)
{
    Record r = {0};
    DWORD Err = m_DbMgr.ReadRecord(Index, (BYTE *)&r, sizeof(Record), NULL);
    if (Err != ERROR_SUCCESS)
        return Err;

    if (pId)
        *pId = r.Id;
    if (pDraft)
        *pDraft = r.Draft;

    return ERROR_SUCCESS;
}

DWORD CDraftsDb::Set(UINT Index, CString Draft)
{
    UINT Id = 0;
    DWORD Err = Get(Index, &Id, NULL);     // Will do all sanity for us
    if (Err != ERROR_SUCCESS)
        return Err;

    Record r = {0};
    HRESULT hr = StringCchCopy(
        r.Draft,
        sizeof(r.Draft) / sizeof(TCHAR),
        Draft);
    if (FAILED(hr))
        return ERROR_INSUFFICIENT_BUFFER;

    r.Id = Id;

    return m_DbMgr.WriteRecord(Index, (BYTE *)&r, sizeof(Record));
}

DWORD CDraftsDb::GetFromId(UINT Id, CString *pDraft, UINT *pIndex)
{
    UINT i = 0;
    Record r = {0};
    DWORD Err = m_DbMgr.ReadRecord(i, (BYTE *)&r, sizeof(Record), NULL);
    while (Err == ERROR_SUCCESS)
    {
        if (Id == r.Id)
        {
            if (pDraft)
                *pDraft = r.Draft;
            if (pIndex)
                *pIndex = i;

            return ERROR_SUCCESS;
        }

        i++;
        Err = m_DbMgr.ReadRecord(i, (BYTE *)&r, sizeof(Record), NULL);
    }

    return ERROR_NOT_FOUND;
}
